package com.jiang.utils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;

import org.apache.commons.lang3.StringUtils;

import com.jiang.factory.SmartFactory;
import com.jiang.servlet.DispatcherServlet;
import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;

/**
 * @author Administrator
 * @后台对前端传来的数据进行自动验证(这里验证完毕后才能向后自动装配打包)
 */
public class ValidationUtils {

	/*
	 * 验证功能函数
	 *  <li>map中存放result true或者false</li>
	 *  <li> 如果是false, 再存一个errors map 里面存放属性和错误信息</li>
	 */
	public static Map<String, Object> validate(DispatcherServlet servlet) {

		Map<String, Object> resultMap = new HashMap<>();
		Map<String,String> errors = new HashMap<>();
		// 如果没有封装那就使用原生的HttpServletRequest
		// 获取配置文件中的验证参数配置
		try{
			String rule = servlet
					.getValidationInfo(servlet.getClass().getSimpleName() + "." + servlet.getInvokeMethodName() + ".rules");
			// 根据配置文件中的参数配置验证，逐一验证
			String params[] = rule.split("\\|");
			// 如果配置文件中没有配置，则不需要验证
			if(params!=null){
				for (String param : params) {
					// param ==> emp.empNo:Long
					validateValue(param,errors,servlet);
				}
			}
		}catch(Exception e){
			String key = servlet.getClass().getSimpleName() + "." + servlet.getInvokeMethodName() + ".rules";
			System.out.println("验证配置文件没有找到相应值: "+ key);
		}
		if(errors.size()==0){
			// 说明验证通过 无错误(或者根本不需要验证)
			resultMap.put("result", true);
		}else{
			resultMap.put("result", false);
			resultMap.put("errors", errors);
		}
		return resultMap;
	}
	
	/**
	 * @每个具体的验证实现
	 * @param   param ==> emp.empNo:Long
	 * @param errors
	 */
	private static void validateValue(String param, Map<String, String> errors,DispatcherServlet servlet) {
		// 记住要考虑表单封装(multipart)
		String[] paraAndType = param.split("\\:");
		String paramRealName = paraAndType[0]; // emp.empNo
		String type = paraAndType[1];
		String value = "";
		// 这里要检测一下是否存在表单封装
		if(servlet.isMuitiPart()){
			SmartUpload smartUpload = SmartFactory.getInstance();
			try {
				smartUpload.initialize(servlet.getServletConfig(), servlet.getRequest(), servlet.getResponse());
				smartUpload.upload();
				value = smartUpload.getRequest().getParameter(paramRealName);
			} catch (ServletException | IOException | SmartUploadException e) {
				e.printStackTrace();
			}
		}else{
			value = servlet.getRequest().getParameter(paramRealName);
		}
			if (StringUtils.isNotBlank(type)) {
				// 字符串判断是否各种类型使用正则表达式
				switch (type) {
					case "int":
					case "Integer":
						if(!validateNumber(value)){
							errors.put(paramRealName, servlet.getMsg("validation"+"."+type+".msg"));
						}
						break;
					case "long":
					case "Long":
						if(!validateNumber(value)){
							errors.put(paramRealName, servlet.getMsg("validation"+"."+type+".msg"));
						}
						break;
					case "double":
					case "Double":
						if(!validateDouble(value)){
							errors.put(paramRealName, servlet.getMsg("validation"+"."+type+".msg"));
						}
						break;
					case "date":
					case "Date":
						if(!validateDate(value)){
							errors.put(paramRealName, servlet.getMsg("validation"+"."+type+".msg"));
						}
						break;
					case "String":
						if(!validateEmpty(value)){
							errors.put(paramRealName, servlet.getMsg("validation.empty.msg"));
						}
					break;	
			}
		}

	}
	
	
	/**
	 * @验证是否为空
	 * @param str
	 * @return
	 */
	public static boolean validateEmpty(String str){
		
		return StringUtils.isNotBlank(str);
	}
	
	/**
	 * 正则表达式验证
	 * @param str
	 * @param reg
	 * @return
	 */
	public static boolean validateReg(String str, String reg){
		
		if(validateEmpty(str)){
			return str.matches(reg);
		}
		return false;
	}
	
	/**
	 * 判断是否为整数
	 * @param str
	 * @return
	 */
	public static boolean validateNumber(String str){
		
		if(validateEmpty(str)){
			return validateReg(str, "\\d+");
		}
		return false;
	}
	
	/**
	 * 判断是否是小数
	 * @param str
	 * @return
	 */
	public static boolean validateDouble(String str) {
		if (validateEmpty(str)) {
			return validateReg(str, "\\d+(\\.\\d+)?");
		}
		return false;
	}
	
	/**
	 * @判断是否为日期
	 * @param str
	 * @return
	 */
	public static boolean validateDate(String str) {
		if (validateEmpty(str)) {
			if(validateReg(str, "\\d{4}-\\d{2}-\\d{2}") || validateReg(str,"\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * @验证是否相同
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static boolean validateSame(String str1, String str2){
		
		if(validateEmpty(str1) && validateEmpty(str2)){
				return str1.equalsIgnoreCase(str2);
		}
		return false;
	}
}
